package com.beone.admin.config.druid;

import com.baomidou.mybatisplus.entity.GlobalConfiguration;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
import com.baomidou.mybatisplus.spring.boot.starter.MybatisPlusProperties;
import com.base.common.datasource.DbContextHolder;
import com.beone.admin.config.mybatis.ReadWriteSplitRoutingDataSource;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * @title
 * @Author 覃球球
 * @Version 1.0 on 2017/12/7.
 * @Copyright 长笛龙吟
 */
@SuppressWarnings("SpringJavaAutowiringInspection")
@Configuration
@AutoConfigureAfter({DruidDataSourceConfig.class})
@MapperScan("com.beone.admin.mapper*") //扫描Mapper指向值的包位置
public class MybatisConfiguration { // extends MybatisAutoConfiguration {

    private static Logger logger = LoggerFactory.getLogger(MybatisConfiguration.class);

    @Resource(name = "masterDataSource")
    private DataSource masterDataSource;

   /* @Resource(name = "slaveDataSource")
    private DataSource slaveDataSource;*/

    @Autowired
    private MybatisPlusProperties properties;



    @Bean
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        logger.info("-------------------- sqlSessionFactory init ---------------------");
        //SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        bean.setDataSource(roundRobinDataSouceProxy());
        bean.setTypeAliasesPackage(properties.getTypeAliasesPackage());
        if(!ObjectUtils.isEmpty(properties.getMapperLocations())){
            bean.setMapperLocations(properties.resolveMapperLocations());
        }
        bean.setMapperLocations(properties.resolveMapperLocations());
        Interceptor[] arrays = {paginationInterceptor()};
        bean.setPlugins(arrays);
        bean.setGlobalConfig(this.getGlobalConfiguration()); //全局配置
        return bean.getObject();
    }

    /**
     * MyBatis Plus 配置
     * @return
     */
    @Bean
    public GlobalConfiguration getGlobalConfiguration(){
        GlobalConfiguration config = new GlobalConfiguration();
        /**
         *  主键策略配置
         *      可选参数  AUTO->`0`("数据库ID自增") INPUT->`1`(用户输入ID") ID_WORKER->`2`("全局唯一ID")
         *      UUID->`3`("全局唯一ID")
         */
        config.setIdType(2); //ID_WORKER->`2`("全局唯一ID")
        /**
         // 数据库类型配置
         // 可选参数（默认mysql）
             MYSQL->`mysql` ORACLE->`oracle` DB2->`db2` H2->`h2`
             HSQL->`hsql`  SQLITE->`sqlite`  POSTGRE->`postgresql`
             SQLSERVER2005->`sqlserver2005`  SQLSERVER->`sqlserver`
         */
        config.setDbType("mysql");
        //全局表为下划线命名设置 true
        config.setDbColumnUnderline(true);
        return config;
    }

    /**
     * mybatis-plus分页插件<br>
     * 文档：http://mp.baomidou.com<br>
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        paginationInterceptor.setLocalPage(true);// 开启 PageHelper 的支持
        return paginationInterceptor;
    }



    @Bean
    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    @Bean
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        return new DataSourceTransactionManager(roundRobinDataSouceProxy());
    }

    /**
     * 定义数据源的AOP切面，该类控制了使用Master还是Slave。
     *
     * 如果使用读数据源，在Service层的方法加 @ReadOnlyConnection注解；其它默认为Master Datasource
     *
     */
    @Bean
    public AbstractRoutingDataSource roundRobinDataSouceProxy(){
        ReadWriteSplitRoutingDataSource proxy = new ReadWriteSplitRoutingDataSource();
        Map<Object,Object> targetDataResources = new HashMap<Object, Object>();
        targetDataResources.put(DbContextHolder.DbType.MASTER,masterDataSource);
//        targetDataResources.put(DbContextHolder.DbType.SLAVE,slaveDataSource);
        proxy.setDefaultTargetDataSource(masterDataSource);
        proxy.setTargetDataSources(targetDataResources);
        return proxy;
    }
}
